/**
  ******************************************************************************
  * @file    main.c
  * @author  MCU Application Team
  * @brief   Main program body
  * @date
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2023 Puya Semiconductor Co.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by Puya under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "sys.h"
#include "app.h"
#include "timer.h"
#include "mypwm.h"
#include "remote.h"
#include "led.h"
#include "main.h"
/* Private define ------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/


/* Private user code ---------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/

ADC_HandleTypeDef             AdcHandle;
ADC_ChannelConfTypeDef        sConfig;

#define ADC_MIN               900

volatile uint32_t adc_height = 0;
volatile uint8_t flag_music_in = 0;




//void FLASH_Config(void)
//{
//	FLASH_OBProgramInitTypeDef OBInitCfg;
//	if(READ_BIT(FLASH->OPTR, FLASH_OPTR_NRST_MODE) == 0)//复位输入
//	{
//		
//		HAL_FLASH_Unlock(); /* 解锁 FLASH */
//		HAL_FLASH_OB_Unlock(); /* 解锁 FLASH OPTION */
//		
//		OBInitCfg.USERType = OB_USER_BOR_EN | OB_USER_BOR_LEV | OB_USER_IWDG_SW | OB_USER_NRST_MODE | OB_USER_nBOOT1;
//		/* BOR 不使能/BOR 上升 3.2,下降 3.1/软件模式看门狗/RST 改为 GPIO/System memory 作为启动区 */
//		OBInitCfg.USERConfig =OB_BOR_DISABLE | OB_BOR_LEVEL_3p1_3p2 | OB_IWDG_SW | OB_RESET_MODE_GPIO | OB_BOOT1_SYSTEM;
//		
///////////		OBInitCfg.RDPLevel =OB_RDP_LEVEL_1;//使能读保护
//		/* 启动 option byte 编程 */
//		HAL_FLASH_OBProgram(&OBInitCfg);
//		HAL_FLASH_Lock(); /* 锁定 FLASH */
//		HAL_FLASH_OB_Lock(); /* 锁定 FLASH OPTION */
//		
//		/* 产生一个复位， option byte 装载 */
//		HAL_FLASH_OB_Launch();
//	}
//}

/**
  * @brief  ADC配置函数
  * @param  无
  * @retval 无
  */
void APP_ADCConfig(void)
{
  __HAL_RCC_ADC_FORCE_RESET();
  __HAL_RCC_ADC_RELEASE_RESET();
  __HAL_RCC_ADC_CLK_ENABLE();                                                     /* 使能ADC时钟 */

  AdcHandle.Instance = ADC1;
  if (HAL_ADCEx_Calibration_Start(&AdcHandle) != HAL_OK)                          /* ADC校准 */
  {
    Error_Handler();
  }
  AdcHandle.Instance                   = ADC1;                                    /* ADC*/
  AdcHandle.Init.ClockPrescaler        = ADC_CLOCK_SYNC_PCLK_DIV4;                /* 模拟ADC时钟源为PCLK/4*/
  AdcHandle.Init.Resolution            = ADC_RESOLUTION_12B;                      /* 转换分辨率12bit*/
  AdcHandle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;                     /* 数据右对齐 */
  AdcHandle.Init.ScanConvMode          = ADC_SCAN_DIRECTION_BACKWARD;              /* 扫描序列方向：向上(从通道0到通道11)*/
  AdcHandle.Init.EOCSelection          = ADC_EOC_SINGLE_CONV;                     // 序列完成时才触发EOC
  AdcHandle.Init.LowPowerAutoWait      = ENABLE;                                  /* 等待转换模式开启 */
  AdcHandle.Init.ContinuousConvMode    = DISABLE;                                /* 单次转换模式 */
  AdcHandle.Init.DiscontinuousConvMode = ENABLE;                                 /* 不使能非连续模式 */
  AdcHandle.Init.ExternalTrigConv      = ADC_EXTERNALTRIGCONV_T1_TRGO;            // 用定时器 TRGO 触发
  AdcHandle.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_RISING;           /* 触发边沿无 */

  AdcHandle.Init.Overrun               = ADC_OVR_DATA_OVERWRITTEN;                /* 当过载发生时，覆盖上一个值*/
  AdcHandle.Init.SamplingTimeCommon    = ADC_SAMPLETIME_41CYCLES_5;              // 先留长一点，抗源阻
  if (HAL_ADC_Init(&AdcHandle) != HAL_OK)                                         /* ADC初始化*/
  {
    Error_Handler();
  }

	//   /* 清除所有通道 */
  // WRITE_REG(ADC1->CHSELR,0);
	
	//   /* 配置选择的通道 */
  sConfig.Rank         = ADC_RANK_CHANNEL_NUMBER;                             
  sConfig.Channel      = ADC_CHANNEL_4;                                      
  if (HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK)       
  {
    Error_Handler();
  }
	
//	/* 配置 Rank1 = VREFINT (内部通道, 通常编号为 ADC_CHANNEL_VREFINT 或 数字) */
//	sConfig.Channel = ADC_CHANNEL_VREFINT; // 有的 HAL 名称为 ADC_CHANNEL_17 或 ADC_CHANNEL_VREFINT
//	sConfig.Rank = 2; // Rank = 2
//	HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
	
	
	if (HAL_ADC_Start_IT(&AdcHandle) != HAL_OK)                         /* 启动ADC并使能ADC中断 */
	{
		Error_Handler();
	}	
}



volatile uint16_t mic_val[10] = {0};
volatile uint32_t vref_val = 0;

/**
  * @brief  ADC转换完成回调函数
  * @param  hadc：ADC句柄
  * @retval 无
  */
 void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
 { 
	  if (hadc->Instance == ADC1)
    {
			uint16_t mic_num = 0;
			
//			for(int i = 0;i<10;i++)
////			{
//				mic_val[0] = hadc->Instance->DR;
//				mic_val[1] = hadc->Instance->DR;
//				mic_val[2] = hadc->Instance->DR;
//				mic_num += mic_val[0] + mic_val[1] + mic_val[2];
////			}
			
			
			for(int i = 0;i<10;i++)
			{
				mic_val[i] = hadc->Instance->DR;
				mic_num += mic_val[i];
			}
        // ========= 在这里做归一化 / 包络检测 =========
      uint16_t ratio = mic_num / 10;
        // TODO: 加入你的滤波、门限、flag_music_in 更新逻辑
			
//			if(flag_music_in == 0 && vref_val < 20)
//			{
//				vref_val ++;
//			}
			if(ratio >= 900)
			{
				flag_music_in = 1;
				vref_val = 0;
			}
				
    }

 }

 
uint16_t timeNum = 0;
uint8_t timeflag = 0;
// 中断服务函数
void TIM16_IRQHandler(void)
{
    if (__HAL_TIM_GET_FLAG(&htim16, TIM_FLAG_UPDATE) != RESET)
    {
        if (__HAL_TIM_GET_IT_SOURCE(&htim16, TIM_IT_UPDATE) != RESET)
        {
            __HAL_TIM_CLEAR_IT(&htim16, TIM_IT_UPDATE);
            // 在此处添加中断处理代码
					
						Remote_count();
//						timeNum++;
//						if(timeNum >= 100)
//						{
//								timeNum = 0;
//									
//								if (HAL_ADC_Start_IT(&AdcHandle) != HAL_OK)                         /* 启动ADC并使能ADC中断 */
//								{
//									Error_Handler();
//								}
//								timeflag = 1;
//						}

        }
    }
}
// /**
//   * @brief  ADC 转换函数
//   * @param  Channel: 待转换的通道 
//   * @retval ADC 转换值
//   */
// uint32_t APP_ADCConvert(void)
// {
//   uint16_t adcvalue = 0;
// 
//   /* 开始转换 */
//   HAL_ADC_Start(&AdcHandle);  
//  
//   /* 轮询等待ADC转换结束 */
//   HAL_ADC_PollForConversion(&AdcHandle, 1000000);        
//  
//   /* 读取ADC转换值 */
//   adcvalue = (&AdcHandle)->Instance->DR;    
//   return (uint32_t)adcvalue;
// }
// 
// 
// #define ADC_FILTER_LEN  10
// uint16_t adc_buf[ADC_FILTER_LEN];
// uint8_t  adc_index = 0;
// uint16_t get_adc_filtered(void)
// {
//     uint32_t sum = 0;
//     adc_buf[adc_index++] = APP_ADCConvert();
//     if(adc_index >= ADC_FILTER_LEN) adc_index = 0;

//     for(int i=0;i<ADC_FILTER_LEN;i++)
//         sum += adc_buf[i];

//     return (uint16_t)(sum / ADC_FILTER_LEN);
// }


uint32_t currentTick1 ,lastTick1;
// volatile uint32_t  aADCxConvertedData;
/**
  * @brief  应用程序入口函数.
  * @retval int
  */
int main(void)
{
  /* 初始化所有外设，Flash接口，SysTick */
  HAL_Init();
	
	APP_SystemClockConfig();
	//OPtion选字节，复位脚初始化成普通引脚
//	FLASH_Config();//加上之后灯不亮
	
	// HAL_Delay(3000);

	BSP_USART_Config();
	//通用定时器50us中断初始化
	APP_TIM16_INIT();
	NVIC_Config();
	
	//PWM初始化
	APP_TIM1_INIT();	
//	MX_GPIO_Init();
	APP_TIM1_PWM();


	//红外控制器初始化
	Remote_Init();
	
	//ADC初始化
  APP_ADCConfig();

//	HAL_Delay(2000);
	
  /* 通道1开始输出PWM */
  if (HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1) != HAL_OK)                  
  {
    Error_Handler();
  }

  /* 通道2开始输出PWM */
  if (HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2) != HAL_OK)                  
  {
    Error_Handler();
  }

  /* 通道4开始输出PWM */
  if (HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_4) != HAL_OK)                  
  {
    Error_Handler();
  }	


	//灯的参数初始化
	Light_init();
	NVIC_DisableIRQ(ADC_COMP_IRQn);  // 关闭 ADC 中断
  /* 无限循环 */
  while (1)
  {
		app_function();
//    currentTick1 = HAL_GetTick();
//    aADCxConvertedData = get_adc_filtered();
//		if(currentTick1 - lastTick1 > 10)
//		{	


//			if(adc_height)
//			{
//				adc_height = 0;
//				flag_music_in = 1;

//			}
//			lastTick1 = currentTick1;
//		}	


  }
}






#ifdef  USE_FULL_ASSERT
/**
  * @brief  输出产生断言错误的源文件名及行号
  * @param  file：源文件名指针
  * @param  line：发生断言错误的行号
  * @retval 无
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* 用户可以根据需要添加自己的打印信息,
     例如: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* 无限循环 */
  while (1)
  {
  }
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT Puya *****END OF FILE****/
